package com.fingard.dsp.bank.directbank.hrrz01;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.directbank.hrbb01.HRBB01Base;
import com.fingard.dsp.bank.directbank.hrbb01.HRBB01Header;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.sql.Connection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

public class HRRZ01SinglePay extends HRRZ01Base implements ISinglePay {
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        //返回ATS的对象
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        if ("190801".equals(p_req1908.reqHeader.commandCode)) {//同行
            tmpRetDetail = bankInnerTransfer(p_req1908);
        } else if("190802".equals(p_req1908.reqHeader.commandCode)) {//跨行
            tmpRetDetail = crossBankTransfer(p_req1908);
        } else{
            retAts.writeRespCode("0");
            retAts.writeRespInfo("只支持同行转账和跨行转账");
        }
        if ("-1".equals(tmpRetDetail.respCode) && StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
            tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
        }
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    //跨行转账
    private RetAtsSglDetail crossBankTransfer(ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail retDetail = new RetAtsSglDetail();
        HRRZ01Header header = new HRRZ01Header();
        header.bsnCode = "41004003";
        header.msgType = "1002";
        header.serialNo = p_req1908.singleDetail.askNumber;
        Connection conn = FGBiz.getLocalDbConn();
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        //写入通用的头部节点
        String paySonSeq = getSonSeq(p_req1908.singleDetail.payAct);
        String tmpCur = convertCurToATS(p_req1908.singleDetail.payCur);
        String data = p_req1908.singleDetail.payAct + "|" + p_req1908.singleDetail.payName + "|" + paySonSeq+ "|" + tmpCur + "|" + p_req1908.singleDetail.payAmount +"|" +
                p_req1908.singleDetail.recAct + "|" + p_req1908.singleDetail.recName + "|" + p_req1908.singleDetail.cnapsCode + "|" + "HR8022004";
        header.signature = data;
        writeCommonHeader(xmlWriter,header);
        XElement tmpXElement = new XElement("appBody", "");
        tmpXElement.addChild(new XElement("voucherKind","201"));
        tmpXElement.addChild(new XElement("payAccountType", "2"));
        tmpXElement.addChild(new XElement("bankCode", "105"));
        tmpXElement.addChild(new XElement("sourceFunds", "101"));
        tmpXElement.addChild(new XElement("payAccount", p_req1908.singleDetail.payAct));
        tmpXElement.addChild(new XElement("payAccountName", p_req1908.singleDetail.payName));
        tmpXElement.addChild(new XElement("accountNumber", paySonSeq));//账号子序号
        tmpXElement.addChild(new XElement("currencySymbols", tmpCur));
        tmpXElement.addChild(new XElement("transAmount", p_req1908.singleDetail.payAmount));

        tmpXElement.addChild(new XElement("beneficiaryAccount", p_req1908.singleDetail.recAct));
        tmpXElement.addChild(new XElement("benefixlaryName", p_req1908.singleDetail.recName));
        tmpXElement.addChild(new XElement("pedestrianLineNumber", p_req1908.singleDetail.cnapsCode));
        tmpXElement.addChild(new XElement("benefixlaryBankName", p_req1908.singleDetail.recBankName));
        tmpXElement.addChild(new XElement("benefixlaryName", p_req1908.singleDetail.recName));
        tmpXElement.addChild(new XElement("receiptWay", "1"));
        tmpXElement.addChild(new XElement("orElectr", "0"));
        tmpXElement.addChild(new XElement("modePayment", "2"));
        tmpXElement.addChild(new XElement("abstractCode", "HR8022004"));
        String memo = p_req1908.singleDetail.purpose;
        if(StringHelper.isNullOrEmpty(memo)){
            memo = "转账";
        }
        tmpXElement.addChild(new XElement("remark", memo));

        nodeAnalysis(p_req1908.singleDetail.srcXElement, tmpXElement, getCharset());


        tmpXElement.addChild(new XElement("signData", ""));

        xmlWriter.writeXElement(tmpXElement);
        xmlWriter.writeEndDocument();
        String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(),header.msgType);
        if (tmpStrRet[0].length() == 0) {
            if (getRet(tmpStrRet[1])) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRets[2], tmpSbMsg);
                if (tmpBkReader != null) {
                    String respondCode = tmpRets[0];
                    String respondInfo = tmpBkReader.getFirstText("/resRoot/appHdr/resMsg");
                    if(respondCode.equals("00000000")) {
                        retDetail.respCode = "0";
                        retDetail.respInfo = tmpBkReader.getFirstText("/resRoot/appBody/descriptions");
                        retDetail.reqSeqID = tmpBkReader.getFirstText("/resRoot/appBody/streamNumber");
                        //0：未受理-----落地处理
                        //2：处理中-----发送银企成功
                        //3：处理失败---银企返回失败
                        //4：关闭-------落地退回
                        //6：处理成功---银企返回成功
                        retDetail.transState =p_req1908.reqHeader.commandCode + respondCode + tmpBkReader.getFirstText("/resRoot/appBody/clearState");
                        retDetail.payInfoCode = retDetail.transState;
                        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                        JDBCHelper.update(conn, INSERTSEQ, new Object[]{uuid, p_req1908.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1908.reqHeader.reqSeqID, tmpBkReader.getFirstText("/resRoot/appBody/streamNumber")});
                    }else{
                        retDetail.respCode = "-1";
                        retDetail.respInfo = respondInfo;
                    }
                } else {
                    retDetail.respCode = "-1";
                    retDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = tmpRets[1];
            }
        } else if (tmpStrRet[0].equals(ConnState.FAIL)) {
            retDetail.respCode = "0";
            retDetail.respInfo = tmpStrRet[1];
            retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
            retDetail.transState = PaymentState.FAIL_Payment;
            retDetail.payInfoCode = tmpStrRet[0];
        } else {
            retDetail.respCode = "-1";
            retDetail.respInfo = tmpStrRet[1];
        }
        return retDetail;
    }

    //同行转账
    private RetAtsSglDetail bankInnerTransfer(ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail retDetail = new RetAtsSglDetail();
        HRRZ01Header header = new HRRZ01Header();
        header.bsnCode = "41004001";
        header.msgType = "1002";
        header.serialNo = p_req1908.singleDetail.askNumber;
        Connection conn = FGBiz.getLocalDbConn();
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        //写入通用的头部节点
        String paySonSeq = getSonSeq(p_req1908.singleDetail.payAct);
        String recSonSeq = getSonSeq(p_req1908.singleDetail.recAct);
        String recCur = convertCurToBank(p_req1908.singleDetail.recCur);
        String tmpCur = convertCurToBank( p_req1908.singleDetail.payCur);
        String data = p_req1908.singleDetail.payAct + "|"+ paySonSeq +"|" + p_req1908.singleDetail.payName + "|" + tmpCur + "|" + p_req1908.singleDetail.payAmount +"|" +
                p_req1908.singleDetail.recAct + "|" +recSonSeq + "|"+ p_req1908.singleDetail.recName + "|" + recCur + "|" + "HR2123003";
        header.signature = data;
        writeCommonHeader(xmlWriter, header);
        XElement tmpXElement = new XElement("appBody", "");
        tmpXElement.addChild(new XElement("fundSource", "1"));
        tmpXElement.addChild(new XElement("customerAccount", p_req1908.singleDetail.payAct));
        //子账号序号
        tmpXElement.addChild(new XElement("customerKidAccountSeq",paySonSeq));
        tmpXElement.addChild(new XElement("accountName", p_req1908.singleDetail.payName));
        tmpXElement.addChild(new XElement("currencyType", tmpCur));
        tmpXElement.addChild(new XElement("accountMoney", p_req1908.singleDetail.payAmount));

        tmpXElement.addChild(new XElement("accountTicketType", "0"));
        tmpXElement.addChild(new XElement("newCertType", "201"));
        tmpXElement.addChild(new XElement("fundWhere", "1"));
        tmpXElement.addChild(new XElement("receiveCustomerAccount", p_req1908.singleDetail.recAct));

        tmpXElement.addChild(new XElement("receiveKidAccountSeq", recSonSeq));
        tmpXElement.addChild(new XElement("receiveAccountName", p_req1908.singleDetail.recName));

        tmpXElement.addChild(new XElement("receiveCurrencyType",recCur));

        tmpXElement.addChild(new XElement("receiveTicketType","0"));

        tmpXElement.addChild(new XElement("pointCode","HR2123003"));
        String purpose = p_req1908.singleDetail.purpose;
        if(StringHelper.isNullOrEmpty(purpose)){
            purpose = "转账";
        }
        tmpXElement.addChild(new XElement("pointDescription",purpose));
        String memo = p_req1908.singleDetail.memo;
        if(StringHelper.isNullOrEmpty(memo)){
            memo = "转账";
        }
        tmpXElement.addChild(new XElement("label",memo));
        tmpXElement.addChild(new XElement("transferType", "1"));
        tmpXElement.addChild(new XElement("notCancelCurrencyType", "001"));
        tmpXElement.addChild(new XElement("feeType","0"));

        nodeAnalysic(p_req1908.singleDetail.srcXElement, tmpXElement, getCharset());
        xmlWriter.writeXElement(tmpXElement);
        xmlWriter.writeEndDocument();
        String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(),header.msgType);
        if (tmpStrRet[0].length() == 0) {
            if (getRet(tmpStrRet[1])) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRets[2], tmpSbMsg);
                if (tmpBkReader != null) {
                    String respondCode = tmpRets[0];
                    String respondInfo = tmpBkReader.getFirstText("/resRoot/appHdr/resMsg");
                    if(respondCode.equals("00000000")) {
                        retDetail.respCode = "0";
                        retDetail.respInfo = tmpBkReader.getFirstText("/resRoot/appBody/reminderMsg");
                        retDetail.reqSeqID = tmpBkReader.getFirstText("/resRoot/appBody/bankUserNo");
                        //成功：90  失败：99  可疑：98
                        retDetail.transState = p_req1908.reqHeader.commandCode + respondCode + tmpBkReader.getFirstText("/resRoot/appBody/groundState");
                        retDetail.payInfoCode = retDetail.transState;
                        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                        JDBCHelper.update(conn, INSERTSEQ, new Object[]{uuid, p_req1908.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1908.reqHeader.reqSeqID, tmpBkReader.getFirstText("/resRoot/appBody/bankUserNo")});
                    }else{
                        retDetail.respCode = "-1";
                        retDetail.respInfo = respondInfo;
                    }
                } else {
                    retDetail.respCode = "-1";
                    retDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = tmpRets[1];
            }
        } else if (tmpStrRet[0].equals(ConnState.FAIL)) {
            retDetail.respCode = "0";
            retDetail.respInfo = tmpStrRet[1];
            retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
            retDetail.transState = PaymentState.FAIL_Payment;
            retDetail.payInfoCode = tmpStrRet[0];
        } else {
            retDetail.respCode = "-1";
            retDetail.respInfo = tmpStrRet[1];
        }
        return retDetail;
    }

    //状态查询
    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        //返回ATS的对象
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail retDetail = new RetAtsSglDetail();
        Connection conn = FGBiz.getLocalDbConn();
        HRRZ01Header header = new HRRZ01Header();
        if(p_req1944.reqHeader.commandCode.equals("190801")){
            header.bsnCode = "41004002";
        }else{
            header.bsnCode = "41004004";
        }
        header.msgType = "1001";
        header.serialNo = p_req1944.reqHeader.transSeqID;
        Map<String, Object> selMap = JDBCHelper.execQuerySingle(conn, SELECTSEQ, new Object[]{p_req1944.reqHeader.reqSeqID, p_req1944.reqHeader.bankCode});
        if(selMap!=null){
            p_req1944.reqHeader.transSeqID = selMap.get("BANKREQSEQID").toString();
            WriteBankLogLn("映射核心流水号为："+p_req1944.reqHeader.transSeqID);
        }
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        writeCommonHeader(xmlWriter, header);
        xmlWriter.writeStartElement("appBody");
        xmlWriter.writeElementString("beginNum", "0");
        xmlWriter.writeElementString("queryNum", "20");
        if(header.bsnCode.equals("41004002")){
            xmlWriter.writeElementString("bankUserNo", p_req1944.reqHeader.transSeqID);
        }else{
            xmlWriter.writeElementString("streamNumber", p_req1944.reqHeader.transSeqID);
        }
        xmlWriter.writeEndDocument();
        try {
            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(),header.msgType);
            if (tmpStrRet[0].length() == 0) {
                if (getRet(tmpStrRet[1])) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRets[2], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String respondCode = tmpRets[0];
                        String respondInfo = tmpBkReader.getFirstText("/resRoot/appHdr/resMsg");
                        if(respondCode.equals("00000000")) {
                            retDetail.reqSeqID = p_req1944.askNumber;
                            retDetail.respCode = "0";
                            if (header.bsnCode.equals("41004002")) {
                                retDetail.respInfo = tmpBkReader.getFirstText("/BankData/opRep/opResult/responseResult");
                                //交易状态与电子金融平台保持一致。
                                retDetail.transState = "190801" + respondCode + tmpBkReader.getFirstText("/resRoot/appBody/groundStateResultDetailList/array/row/groundState");
                            } else {
                                retDetail.respInfo = tmpBkReader.getFirstText("/resRoot/appBody/payResult/array/row/settleReason");
                                //交易状态与电子金融平台保持一致。
                                //0：未受理-----落地处理
                                //2：处理中-----发送银企成功
                                //3：处理失败---银企返回失败
                                //4：关闭 ------落地退回
                                //6：处理成功---银企返回成功
                                retDetail.transState = "190802" + respondCode + tmpBkReader.getFirstText("/resRoot/appBody/payResult/array/row/clearState");
                            }
                            retDetail.payInfoCode = retDetail.transState;
                        }else{
                            retDetail.respCode = "-1";
                            retDetail.respInfo = respondInfo;
                        }
                    } else {
                        retDetail.respCode = "-1";
                        retDetail.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    retDetail.respCode = "-1";
                    retDetail.respInfo = tmpRets[1];
                }
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception e) {
            retDetail.respCode = "-1";
            retDetail.respInfo = e.getMessage();
            e.printStackTrace();
        }
        retAts.writeRetDetail(retDetail);
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}